<template>
  <div class="common-layout" :style="{ 'background-color': backgroundColor }">
    <el-container>
      <el-aside :style="{ width: sidebarWidth, transition: 'width 0.3s ease' }" class="scrollable-aside">
        <!-- logo -->
        <div class="logo left-db" :class="{ collapsed: isSidebarCollapsed }">
          <div class="back-info">
            <el-button v-if="!isSidebarCollapsed" @click="goBack" class="back-btn" color="#626aef" :icon="ArrowLeft" plain></el-button>
            <img src="@/assets/vue.svg" alt="Vue Logo" />
          </div>
          <span class="know-title" v-show="!isSidebarCollapsed">知识管理平台</span>
        </div>
        <!-- search -->
        <div style="display: flex; align-items: center; padding: 20px; background-color: var(--el-menu-bg-color);">
          <el-input v-if="!isSidebarCollapsed" placeholder="搜索..." v-model="searchQuery" clearable></el-input>
          <el-icon @click="toggleSidebar" style="margin-left: 5px;"><Menu /></el-icon>
        </div>
         <!-- tree component -->
        <TreeComponent
            :operMenu = "operMenu"
            :search-query="searchQuery"
            :tree-data="treeData"
            :default-props="defaultProps"
            :is-sidebar-collapsed="isSidebarCollapsed"
            :trigger-button="triggerButton"
            :sidebar-width="sidebarWidth" 
            @view-click="handleViewClick"
            @node-click="handleNodeClick"
            @drag-start="handleDragStart"
            @drag-end="handleDragEnd"
            @drop="handleDrop"
            @nav-click="handleNavClick"
          />
      </el-aside>
      <!-- 增加scroll size -->
      <div class="drag-bar" @mousedown="startResizing">
        <div @click="toggleSidebar" class="drag-button">
          <el-icon v-if="!isSidebarCollapsed"><CaretLeft /></el-icon>
          <el-icon v-else><CaretRight /></el-icon>
        </div>
        <div class="drag-bar-line"></div>
      </div>
     
      <el-main>
        <div  v-if="hasAttachment">
          <div>
            <el-icon @click="downLoadFile" class="icon-btn"><Download/></el-icon>
            <el-icon v-if="operMenu"  @click="deleteFile" class="icon-btn"><Delete/></el-icon>
            <el-icon v-if="operMenu" @click="editFile" class="icon-btn"><Edit/></el-icon>
          </div>   
          <div>选择其他版本</div>
          <el-select v-model="selectedAttachmentId" placeholder="选择其他版本附件" >
          <el-option
            v-for="item in historyAttachments"
            :key="item.id"
            :label="item.versionDesc"
            :value="item.id"
            @click="switchToHistoryAttachment(item)"
          >
          </el-option>
        </el-select>

        </div>

        <!-- <p v-if="!hasAttachment">请上传附件</p> -->
        <file-preview v-if="showPreview" :file="previewFile" :fileType="fileType" @close="showPreview = false" />
        <el-empty v-else description="选择一个文件以查看其内容" />
      </el-main>
    </el-container>

    <!-- 引入子组件 -->
    <OperationDialog
          :visible="dialogVisible"
          :operation="currentOperation"
          :onSubmit="handleOperationSubmit"
          :nodeData="selectedNode"
          @update:visible="dialogVisible = $event"
    />

  </div>
</template>

<script lang="ts">
import { attachmentDownload, attachmentPreview, checkAttachmentExist, deleteAttachment, getNodeHistory } from '@/api/repo/attachment';
import { createNode, deleteNode, getNodeTree, importFile, updateNode } from '@/api/repo/node';
import FilePreview from '@/components/FilePreview/index.vue';
import OperationDialog from '@/components/operDialog/index.vue'; // 假设子组件位于此路径
import download from '@/utils/down/download';
import {
ArrowLeft,
CaretLeft,
CaretRight, CirclePlus, Delete, Edit, Menu, UploadFilled
} from '@element-plus/icons-vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { computed, defineComponent, onMounted, onUnmounted, reactive, ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import TreeComponent from './components/TreeComponent.vue';

export default defineComponent({
  props: {
    operMenu: {
      type: Boolean,
      required: true
    },
  },
  components: {
    FilePreview,
    OperationDialog,
    TreeComponent
  },
  setup() {
    const route = useRoute();

    const router = useRouter();

    // 从 URL 查询参数中获取 ID
    //      const id = ref(route.params?.id);
    //  computed(() => route.query.id);
    const repoId = computed(() => route.params.id);
    // 设置页面背景色
    const backgroundColor = '#f0f2f5';
    // 搜索框绑定的值
    const searchQuery = ref('');

    const hasAttachment = ref(false);
    const historyAttachments = ref([]);
    const selectedAttachmentId = ref<string | null>(null);
    const fileType = ref<string | null>(null);

    // 树的数据（这里用静态数据代替）
    const treeData = ref([
      {
        label: '目录',
        id: 'root',
        repoId: repoId,
        // children: [{ label: '二级 1-1', children: [{ label: '三级 1-1-1' }] }],
      },
    ]);

    // 触发按钮配置
    const triggerButton = [
      { name: '新增', methodName: 'openDialog', icon: CirclePlus, operation: 'create' },
      { name: '编辑', methodName: 'openDialog', icon: Edit , operation: 'edit' },
      { name: '移除', methodName: 'remove', icon: Delete, operation: 'remove' },
      { name: '导入', methodName: 'handleImport', icon: UploadFilled, operation: 'import' }
    ];

    // 树的配置属性
    const defaultProps = { children: 'children', label: 'label' };
    interface Node {
      id: string; // 或者是 number，取决于实际情况
      // ... 其他属性
    }
    // 当前选中的节点
    const selectedNode = ref<Node | null>(null);
    const atthamentDataId = ref<string | null>(null);
    const selectData = ref(null);
    // 对话框相关状态
    const dialogVisible = ref(false);
    const currentOperation = ref('create'); // 默认为新建操作

    // 返回按钮的方法
    const goBack = () => {
        router.push('/home');
    };

    // 处理提交的操作
    const handleOperationSubmit = async (formInfo: any, data: any) => {
      const { attachmentId, versionDesc, type, name, files } = formInfo;
      const newNode = {
        label: name,
        nodeType: type,
        children: type === 'folder' ? [] : undefined,
        id: ''
      };
      // let newTreeNode;
      switch (currentOperation.value) {
        case 'create':
          // 添加新节点到树中
          // 如果有选中的节点，则作为新节点的父节点
          // const parentId = selectedNode.value && selectedNode.value.data ? selectedNode.value.data.id : data.id;
          // const parentId = selectedNode.value?.data.id || null;
          const parentId = selectedNode.value  ? selectedNode.value.id : data.id;
          let addNodeId = await createNode({ repoId: repoId.value, parentId, node: newNode });
          newNode.id = addNodeId;
          // methods.appendNode(selectedNode.value || treeData.value, newTreeNode);
          methods.appendNode(selectedNode.value,newNode);
          break;
        case 'edit':
          if (selectedNode.value) {
            // selectedNode.value.label = name;
            // 更新树中的节点信息
            newNode.id = selectedNode.value.id;
            await updateNode({ nodeId: newNode.id, node: newNode });
            methods.editNode(selectedNode.value,newNode);
          }
          break;
        case 'import':
          // 上传逻辑
          if (files && files.length) {
            // 处理文件上传逻辑
            let formData = new FormData();
            formData.append('nodeId', selectedNode.value.id); // 添加一个简单的键值对
            formData.append('versionDesc', versionDesc);
            formData.append('attachmentId', attachmentId);
            for (let i = 0; i < files.length; i++) {
                formData.append('files', files[i]); // 分别添加每个文件
            }
            await importFile(formData);
            // 导入文件后触发节点的点击
            handleViewClick(selectedNode.value);
          }else{
            // 处理文件上传逻辑
            let formData = new FormData();
            formData.append('nodeId', selectedNode.value.id); // 添加一个简单的键值对
            formData.append('versionDesc', versionDesc);
            formData.append('attachmentId', attachmentId);
            await importFile(formData);
            // 导入文件后触发节点的点击
            // 触发点击的时候有可能事务还没有结束;导致查询结果不一致
            handleViewClick(selectedNode.value);
          }
          break;
      }
      ElMessage.success(`${currentOperation.value === 'import' ? '导入' : '操作'}成功`);
    };

    // 折叠状态
    const isSidebarCollapsed = ref(false);

    // 动态宽度
    let initialSidebarWidth = 450;
    // const sidebarWidth = computed(() => (isSidebarCollapsed.value ? '64px' : `${initialSidebarWidth}px`));
    const sidebarWidth = ref(initialSidebarWidth + 'px');

    // 拖拽条相关变量
    let isResizing = false;
    let startX: number;
    let startWidth: number;

    // 切换侧边栏
    const toggleSidebar = () => {
      isSidebarCollapsed.value = !isSidebarCollapsed.value;
      // 控制侧边栏展示处理
      if (isSidebarCollapsed.value) {
        sidebarWidth.value = '64px';
      } else {
        sidebarWidth.value = initialSidebarWidth + 'px';
      }
    };

    // 开始拖拽
    const startResizing = (event: MouseEvent) => {
      isResizing = true;
      startX = event.clientX;
      startWidth = parseInt(sidebarWidth.value, 10);
      document.addEventListener('mousemove', doResizing);
      document.addEventListener('mouseup', stopResizing);
    };

    // 执行拖拽
    const doResizing = (event: MouseEvent) => {
      if (!isResizing) return;
      const diffX = event.clientX - startX;
      let newWidth = startWidth + diffX;
      const minWidth = 64;
      const maxWidth = window.innerWidth * 0.3;
    
      // 更新宽度并检查是否需要折叠或展开
      if (newWidth < minWidth) {
        newWidth = minWidth;
        isSidebarCollapsed.value = true;
      } else if (newWidth > minWidth && isSidebarCollapsed.value) {
        isSidebarCollapsed.value = false;
      }
    
      if (newWidth > maxWidth) newWidth = maxWidth;
      sidebarWidth.value = newWidth + 'px';
    };

    // 停止拖拽
    const stopResizing = () => {
      isResizing = false;
      document.removeEventListener('mousemove', doResizing);
      document.removeEventListener('mouseup', stopResizing);
    };

    const loadTreeData = async () => {
      try {
        const data = await getNodeTree({repoId:repoId.value});
        treeData.value = data; // 假设返回的数据可以直接赋值给 treeData
      } catch (error) {
        ElMessage.error('加载树形结构失败');
      }
    };

    onMounted(() => {
      document.addEventListener('mouseup', stopResizing);
      // const id = route.params.id;

      // 重置树结构
      loadTreeData();
    });

    onUnmounted(() => {
      document.removeEventListener('mouseup', stopResizing);
    });


    const handleViewClick = async (data: any) => {
      hasAttachment.value = false;
      historyAttachments.value = [];
      selectedAttachmentId.value = null;
      // append file request 
      if (data.nodeType === 'file') {
        try {
          // 获取节点的历史附件
          const historyResponse = await getNodeHistory({ nodeId: data.id });
          historyAttachments.value = historyResponse || [];

          if (historyAttachments.value.length > 0) {
            hasAttachment.value = true;
            selectedAttachmentId.value = historyAttachments.value[0].id; // 默认选中最新的历史附件
            atthamentDataId.value =  selectedAttachmentId.value;
          }

          const checkExist = await checkAttachmentExist({ nodeId: data.id, attachmentId:selectedAttachmentId.value });
          if (checkExist.exist) {
            const attachment = await attachmentPreview({ nodeId: data.id, attachmentId:selectedAttachmentId.value });
            if (attachment) {
              fileType.value = checkExist.fileType;
              previewFile.value = attachment; // 这里假设返回的是可以直接使用的文件对象
              showPreview.value = true;
            }
          } else { 
            showPreview.value = false;
          }
        
        } catch (error) {
          ElMessage.error('加载文件失败');
        }
      } else {
        showPreview.value = false;
      }
    }

    const deleteFile = async () => {
      // 弹出确认对话框
      ElMessageBox.confirm(
        '此操作将永久删除该文件, 是否继续?',
        '提示',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }
      ).then(
        async () => { // 用户点击了“确定”按钮
          try {
            await deleteAttachment({ nodeId: selectedNode.value.id, attachmentId:atthamentDataId.value  });
            ElMessage.success('删除成功');
            loadTreeData(); // 刷新树数据
            handleViewClick(selectedNode.value); // 重新加载当前节点数据
          } catch (error) {
            console.log(error);
            ElMessage.error('删除失败');
          }
      }).catch(() => { // 用户点击了“取消”按钮或关闭了对话框
        ElMessage.info('删除已取消');
      });
    }


    const editFile = async () => {
      currentOperation.value = 'import';
      dialogVisible.value = true;
    }

    const downLoadFile = async (item: any) => {
      // let nodeId = (selectedNode.value as NonNullable<typeof selectedNode.value>).id;
      const checkExist = await checkAttachmentExist({ nodeId: selectedNode.value.id,attachmentId:atthamentDataId.value });
      if (checkExist.exist) {
        const response = await attachmentDownload({ nodeId:  selectedNode.value.id,attachmentId:atthamentDataId.value });
        // 如果 request.download 直接返回 Blob 类型的数据
        if (response instanceof Blob) {
          const url = URL.createObjectURL(response);
          download.default(response, checkExist.fileName); // 使用你的下载工具函数
          URL.revokeObjectURL(url); // 下载完成后释放对象 URL
        } else {
          // 如果不是直接返回 Blob，则需要处理其他情况
          console.error('下载响应不是预期的 Blob 类型');
        }
      } else {
        ElMessage.error('文件不存在');
      }
    }

    // 处理节点点击事件
    const handleNodeClick = async (data: any) => {
      // 避免重复点击的时候加载附件
      if (selectedNode.value == data) {
        return;
      }
      selectedNode.value = data;
      atthamentDataId.value = null;
      if (data.nodeType === 'file') {

      } else {
        showPreview.value = false;
      }
    };

    const switchToHistoryAttachment = async (item: any) => {
      const checkExist = await checkAttachmentExist({ nodeId: selectedNode.value.id,attachmentId:item.id });
      if (checkExist.exist) { 
        atthamentDataId.value = item.id;
        const attachment = await attachmentPreview({ nodeId: selectedNode.value.id, attachmentId: item.id });
        if (attachment) {
          previewFile.value = attachment; // 这里假设返回的是可以直接使用的文件对象
          fileType.value = checkExist.fileType;
          showPreview.value = true;
          showPreview.value = true;
          hasAttachment.value = true;
        }
      } else {
        showPreview.value = false;
      }
    };

    // 节点拖拽开始时触发
    const handleDragStart = (draggingNode: any) => {
      console.log('dragging node:', draggingNode);
    };

    // 节点拖拽结束时触发
    const handleDragEnd = (draggingNode: any, dropNode: any, dropType: string) => {
      console.log('dragging end', draggingNode, dropNode, dropType);
    };

    // 节点被放置时触发
    const handleDrop = (draggingNode: any, dropNode: any, dropType: string, ev: Event) => {
      const newData = [...treeData.value];
      if (dropType === 'inner') {
        dropNode.data.children = dropNode.data.children || [];
        dropNode.data.children.push(draggingNode.data);
      } else {
        const index = newData.findIndex(data => data === draggingNode.data);
        newData.splice(index, 1);
        const targetIndex = newData.findIndex(data => data === dropNode.data);
        if (dropType === 'before') {
          newData.splice(targetIndex, 0, draggingNode.data);
        } else {
          newData.splice(targetIndex + 1, 0, draggingNode.data);
        }
      }
      treeData.value = newData;
    };

    // 定义操作方法
    const methods = reactive({
      append(data: any) {
        const newChild = { label: '新节点', children: [] };
        if (!data.children) {
          data.children = [];

        }
        data.children.push(newChild);
      },

      appendNode(data: any,node: any) {
        if (!data.children) {
          data.children = [];
        }
        data.children.push(node);
      },

      edit(data: any) {
        const newName = prompt('请输入新的标签名', data.label);
        if (newName !== null) {
          data.label = newName;
        }
        selectedNode.value = data; // 设置当前选中的节点
      },

      editNode(data: any, node: any) {
        debugger;
        if (node !== null) {
          data.label = node.label;
          data.nodeType = node.nodeType;
        }
        selectedNode.value = data; // 设置当前选中的节点
      },

      remove(node: any, data: any) {
        const parent = node.parent;
        const children = parent.data.children || parent.data;
        const index = children.findIndex((d: any) => d === data);
        if (index > -1) {
          children.splice(index, 1);
        }
      },

      handleImport(data: any) {
        console.log('导入:', data);
      }
    });
    
    // 定义点击事件处理器
    const handleNavClick = async (methodName: string,operation:string, data: any, node: any) => {
      if (methodName != 'remove') {
        openDialog(operation,data,node);
      } else {
        // await deleteNode({ nodeId: data.id});
        // methods.remove(node,data);
        // 使用 Element Plus 的 ElMessageBox 来显示确认对话框
        ElMessageBox.confirm(
          '此操作将永久删除该节点, 是否继续?',
          '提示',
          {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }
        ).then(async () => { // 用户点击了“确定”按钮
          await deleteNode({ nodeId: data.id });
          methods.remove(node, data);
        }).catch(() => { // 用户点击了“取消”按钮或关闭了对话框
          console.log('删除操作已取消');
        });
      }
    };

    const openDialog =(operation: string, data: any, node: any) =>{
      currentOperation.value = operation;
      dialogVisible.value = true;
      selectData.value = data;
      if (data) selectedNode.value = data;
    }

    // 文件上传相关函数（需根据实际情况实现）
    const fileList = ref([]);

    // 控制预览组件显示与隐藏
    const showPreview = ref(false);
    const previewFile = ref<File | null>(null);

    const handlePreview = (file: any) => {
      previewFile.value = file.raw;
      showPreview.value = true;
    };

    const handleRemove = () => {};
    const beforeRemove = () => {};
    const handleExceed = () => {};

    return {
      ArrowLeft,
      goBack,
      editFile,
      deleteFile,
      downLoadFile,
      fileType,
      hasAttachment,
      historyAttachments,
      selectedAttachmentId,
      switchToHistoryAttachment,
      // dialog
      selectData,
      handleOperationSubmit,
      dialogVisible,
      currentOperation,
      // button
      backgroundColor,
      searchQuery,
      treeData,
      triggerButton,
      defaultProps,
      selectedNode,
      isSidebarCollapsed,
      sidebarWidth,
      toggleSidebar,
      startResizing,
      doResizing,
      stopResizing,
      handleViewClick,
      handleNodeClick,
      handleDragStart,
      handleDragEnd,
      handleDrop,
      methods,
      handleNavClick,
      fileList,
      showPreview,
      previewFile,
      handlePreview,
      handleRemove,
      beforeRemove,
      handleExceed,
    };
  },
});
</script>

<style scoped>
.common-layout {
  width: 100%;
  height: 100vh;
  position: relative; /* 为了确保折叠按钮的绝对定位 */
  color:#000;
}

.back-info{
  display: flex;
  flex-direction: row;
  align-items: center;
}

.back-btn{
  margin-right: 20px;
}

.icon-btn{
  margin-right: 20px;
}

.sidebar-toggle-button {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 10;
}

.el-container {
  height: 100vh;
  background-color: #fff;
}

.vertical-more {
  transform: rotate(-90deg); /* 逆时针旋转90度 */
  display: inline-block; /* 确保旋转应用于整个图标 */
}

.left-db {
  background-color: var(--el-menu-bg-color);
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 5px 25px;
}

.left-db.collapsed {
  justify-content: center;
}

/* 更新 el-main 的背景颜色 */
.el-main {
  background-color: #ffffff; /* 使用白色或者稍微深一点的颜色 */
  padding: 20px; /* 添加一些内边距以提高可读性 */
}

.scrollable-aside {
  overflow-x: hidden; 
  /* 不需要横向滚动 */
  /* overflow-y: auto;    */
  /* 确保垂直滚动可用 */
  height: 100%;      
   /* 确保侧边栏高度与容器一致 */
  /* height: 100vh; */
   /* 确保侧边栏高度占满整个视口 */
  display: flex;
  flex-direction: column;
   /* 使子元素垂直排列 */
}


.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}

.drag-bar ::before{
  width: 80px;
}

.drag-bar {
width: 5px;
cursor: col-resize;
z-index: 100;
background-color: #fff;
/* background-color: transparent; */
 /* 设置背景透明 */
position: relative; /* 确保 .drag-bar-line 绝对定位在其内部 */
}

.drag-bar-line {
position: absolute;
top: 0;
bottom: 0;
left: 100%;
transform: translateX(-50%);
width: 1px;
background-color: #ccc ; /* 确保此行的颜色 */
z-index: 1; /* 确保线条在按钮后面 */
}

.drag-button {
cursor: pointer;
z-index: 2; /* 确保线条在按钮后面 */
position: absolute;
top: 30%;
transform: translateY(-50%);
display: flex;
align-items: center;
justify-content: center;
height: 44px;
width: 14px;
background-color: #d9ebeb;
/* background-color: #e9ebef; */
border-radius: 4px;
}

.button-icon{
  /* padding: 20px; */
  margin: 10px;
}

.trigger-nav{
  font-size: 10px;
}

/* 
.tree-trigger-nav .el-menu-item{
      padding: 5px !important;
      height: 35px ;
  } */

</style>